﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rabbit.Model;
using System.Diagnostics;
using System.Threading;
using System.IO;
using Rabbit.Utils;

namespace Rabbit.BusinessLogicLayer
{
    public class StatusesBL
    {
        #region GetFriendsStatus
        //public static int Count = 10;
        //private static Statuses friendsStatuses;
        private static int NextFriendsStatusCursorID = -1;
        internal static List<Status> GetMoreFriendsStatuses()
        {
            string parameters = "cursor=" + NextFriendsStatusCursorID + "&count=" + Utils.Configuration.PageSize;

            //get the status string
            string statusString = GetFriendsStatusesString(parameters);

            //deserialize the string
            Statuses statues = WrappedJsonHelper.Deserialize<Statuses>(statusString);
            GetForwardedStatusPicture(statues.StatusList);
            StatusesBL.GetStatusCommentAndTransmitCount(statues.StatusList);
            NextFriendsStatusCursorID = statues.CursorID;
            return statues.StatusList;
        }

        private static string GetFriendsStatusesString(string parameters)
        {
            return RequestHelper.SendRequest("statuses/friends_timeline.json", parameters);
        }

        internal static List<Status> GetFriendsStatuses(long? lastSinceID=null)
        {
            string parameters = "cursor=-1";
            if (lastSinceID != null)
            {
                parameters += "&since_id=" + lastSinceID.Value;
            }
            else
            {
               parameters += "&count=" + Utils.Configuration.PageSize;
            }

            string statusString = GetFriendsStatusesString(parameters);
            Statuses statuses = WrappedJsonHelper.Deserialize<Statuses>(statusString);

            if (NextFriendsStatusCursorID == -1)
            {
                NextFriendsStatusCursorID = statuses.CursorID;
            }
            return statuses.StatusList;
        }

        /// <summary>
        /// check whether the status in the list is a forwared status, if true, check whether
        /// it has an image, get the orignal status's image
        /// </summary>
        /// <param name="statusList">the modifed status</param>
        internal static void GetForwardedStatusPicture(List<Status> statusList)
        {
            //if the status is a forwarded status and the orginal status has a picture
            for (int i = 0; i < statusList.Count; i++)
            {
                if (statusList[i].InReplyToHasImage && statusList[i].InReplyToStatusId!=0)
                {
                    Status translatedStatus = GetStatusDetailInfo(statusList[i].InReplyToStatusId);
                    if (translatedStatus != null)
                    {
                        statusList[i].InReplyToSmallImageUrl = translatedStatus.SmallPic;
                        statusList[i].InReplyToMiddleImageUrl = translatedStatus.MiddlePic;
                    }
                }
            }
        }

        internal static void GetStatusCommentAndTransmitCount(List<Status> statusList)
        {
            try
            {
                string statusIDs = "";

                //loop status list to build status id list(split by comma)
                int idcount = 0;
                for (int i = 0; i < statusList.Count && idcount < 50; i++)
                {
                    statusIDs += statusList[i].Id + ",";

                    idcount++;
                    if (statusList[i].InReplyToStatusId!=0)
                    {
                        statusIDs += statusList[i].InReplyToStatusId + ",";
                        idcount++;
                    }
                }

                //remove the last comma
                if (statusIDs.Length > 0)
                {
                    statusIDs = statusIDs.Remove(statusIDs.Length - 1);//remove the last id
                }

                string statusCount = RequestHelper.SendRequest("statuses/counts.json", "ids=" + Utils.UrlEncoder.UrlEncode(statusIDs));
                List<StatusCountAttribute> lstCount = WrappedJsonHelper.Deserialize<List<StatusCountAttribute>>(statusCount);

                //loop the returned status count attribute list, reset the comment count and transmit count value in Status List
                statusList.ForEach(s =>
                {
                    StatusCountAttribute sca = lstCount.Find(sc => sc.Id == s.Id);
                    if (sca != null)
                    {
                        s.CommentsCount = sca.CommentsCount;
                        s.TransmitCount = sca.TransmitCount;
                    }
                    sca = lstCount.Find(sc => sc.Id == s.InReplyToStatusId);
                    if (sca != null)
                    {
                        s.InReplyToCommentsCount = sca.CommentsCount;
                        s.InReplyToTransmitCount = sca.TransmitCount;
                    }
                });
            }
            catch (Exception ex)
            {
                //don't throw any exception here, cause it is not important
                LogHelper.LogError(ex);
            }
        }
        #endregion

        #region Get Status Detail Info
        public static Status GetStatusDetailInfo(long statusID)
        {
            string result = statusOperation("", "statuses/show/" + statusID + ".json", "Get");
            Status status = WrappedJsonHelper.Deserialize<Status>(result);
            List<Status> tempList = new List<Status>();
            tempList.Add(status);
            GetForwardedStatusPicture(tempList);
            return status;
        }
        #endregion

        #region Get Status' Comments
        public static List<Comment> GetStatusComments(string statusID)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region UpdateStatus
        /// <summary>
        /// update my status
        /// </summary>
        /// <param name="statusText">the status text</param>
        public static Status UpdateMyStatus(string statusText)
        {
            string result = statusOperation("status=" + Utils.UrlEncoder.UrlEncode(statusText));
            return WrappedJsonHelper.Deserialize<Status>(result);
        }
        public static Status UpdateMyStatusWithPicture(string pictureRemark, Stream pictureStream)
        {
            string result = RequestHelper.SendRequestWithPicture("statuses/upload.json", Utils.UrlEncoder.UrlEncode(pictureRemark), pictureStream);
            return WrappedJsonHelper.Deserialize<Status>(result);
        }

        public static Status ReplyToStatus(string statusText, long replyToStatusID)
        {
            string result = statusOperation("comment=" + Utils.UrlEncoder.UrlEncode(statusText) + "&id=" + replyToStatusID, "statuses/comment.json");
            return WrappedJsonHelper.Deserialize<Status>(result);
        }

        public static Status ReplyToComment(string statusText, long replyToStatusID, long replyToUserID)
        {
            string result = statusOperation("comment=" + Utils.UrlEncoder.UrlEncode(statusText) + "&id=" + replyToStatusID + "&reply_user_id=" + replyToUserID, "statuses/comment.json");
            return WrappedJsonHelper.Deserialize<Status>(result);
        }
        #endregion

        private static string statusOperation(string parameter, string url = "statuses/update.json", string Method = "Post")
        {
            return RequestHelper.SendRequest(url, parameter, Method);
        }

        #region Add status to favorites
        public static Status AddStatusToFavorites(string statusID)
        {
            string result = statusOperation("", "favourites/create/" + statusID + ".json");
            return WrappedJsonHelper.Deserialize<Status>(result);
        }
        #endregion

        #region Transmite Status
        public static Status ForwardStatus(long statusID, string remark, bool isCommentToOrignalStatus)
        {
            remark = string.IsNullOrEmpty(remark.Replace("*", "")) ? "转发微博" : remark;
            remark = Utils.UrlEncoder.UrlEncode(remark.Trim());

            string result = statusOperation("status=" + remark, "statuses/transmit/" + statusID + ".json");

            if (isCommentToOrignalStatus)
            {
                try
                {
                    ReplyToStatus(remark, statusID);
                }
                catch
                {

                }
            }
            return (Status)WrappedJsonHelper.Deserialize<ForwardedStatus>(result);
        }
        #endregion
    }
}
